package com.joelemon.mockinfluxdbdata.core.config;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.joelemon.mockinfluxdbdata.common.SystemException;
import com.joelemon.mockinfluxdbdata.enums.CommonFlag;
import com.joelemon.mockinfluxdbdata.enums.RunningFlag;
import com.joelemon.mockinfluxdbdata.mock.ConnectConfig;
import com.joelemon.mockinfluxdbdata.datamock.v1.ObjectModelMockConfig;
import com.joelemon.mockinfluxdbdata.mock.MockConfig;
import com.joelemon.mockinfluxdbdata.mock.VisableInfo;
import com.joelemon.mockinfluxdbdata.utils.JsonUtil;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import org.jetbrains.annotations.NotNull;

import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;

/**
 * @Description: mock任务
 * @Author: HJY
 * @Date: 2023/11/20
 */
@Data
@EqualsAndHashCode(callSuper = false)
@NoArgsConstructor
@TableName("mock_task")
public class MockTask implements Delayed {

    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    @TableField("`name`")
    private String name;
    @TableField("`desc`")
    private String desc;
    @TableField("`config_type`")
    private String configType;
    @TableField("`config`")
    private String config;
    @TableField("`connect_config`")
    private String connectConfig;
    @TableField("`status`")
    private RunningFlag status;
    @TableField("`force_stop`")
    private CommonFlag forceStop;
    @TableField(exist = false)
    private MockConfig mockConfig;
    @TableField(exist = false)
    private VisableInfo visableInfo;

    public MockConfig parseConfig() {
        if (configType != null && configType.length() > 0
                && config != null && config.length() > 0) {
            if (mockConfig == null) {
                // 获取类型
                try {
                    Class configClass = Class.forName(configType);
                    mockConfig = (MockConfig)JsonUtil.convertObject(config, configClass);
                } catch (ClassNotFoundException e) {
                    throw new SystemException("类型未找到" + configType);
                }
            }
        }
        return mockConfig;
    }

    public void setConfigStr(ObjectModelMockConfig mockConfig) {
        config = JsonUtil.convertJsonString(mockConfig);
    }

    public ConnectConfig parseConnectConfig() {
        if (connectConfig != null && connectConfig.length() > 0)
            return JsonUtil.convertObject(connectConfig, ConnectConfig.class);
        return null;
    }

    public void setConnectConfigStr(ConnectConfig config) {
        connectConfig = JsonUtil.convertJsonString(config);
    }

    public boolean check() {
        return CommonFlag.NO.equals(forceStop) && config != null && config.length() > 0
                && connectConfig != null && connectConfig.length() > 0;
    }

    @Override
    public long getDelay(@NotNull TimeUnit unit) {
        Long nextRunningTime = mockConfig.getInsertStrategy().getNextRunningTime();

        return Math.max(0, unit.convert(nextRunningTime - System.currentTimeMillis(), TimeUnit.MILLISECONDS));
    }

    @Override
    public int compareTo(@NotNull Delayed o) {
        if (o instanceof MockTask) {
            return Long.compare(mockConfig.getInsertStrategy().getNextRunningTime(),
                    ((MockTask) o).getMockConfig().getInsertStrategy().getNextRunningTime());
        }
        return 0;
    }
}
